package com.xiebishe.mylibrary.common.pageStatus;

import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;

import java.util.ArrayList;

@SuppressWarnings("unused,WeakerAccess")
public abstract class AbstractStatusHandler<VIEW extends ViewGroup> implements StatusHandler {


    private View loadingView;
    private View errorView;
    private View emptyView;
    private VIEW layout;

    private int status = CONTENT;
    private ArrayList<OnStatusChangeListener> listeners = new ArrayList<>();

    public AbstractStatusHandler(@NonNull VIEW layout) {
        this.layout = layout;
    }

    public View getLoadingView() {
        return loadingView;
    }

    public void setLoadingView(View loadingView) {
        if (status == LOADING) {
            throw new IllegalStateException("不能在当前展示状态修改展示view");
        }
        this.loadingView = loadingView;
    }

    public View getErrorView() {
        return errorView;
    }

    public void setErrorView(View errorView) {
        if (status == ERROR) {
            throw new IllegalStateException("不能在当前展示状态修改展示view");
        }
        this.errorView = errorView;
    }

    public View getEmptyView() {
        return emptyView;
    }

    public void setEmptyView(View emptyView) {
        if (status == EMPTY) {
            throw new IllegalStateException("不能在当前展示状态修改展示view");
        }
        this.emptyView = emptyView;
    }

    @Override
    public int getStatus() {
        return status;
    }

    private boolean exitLastState(int state) {
        VIEW layout = this.layout;
        if (layout == null) {
            return false;
        }
        switch (state) {
            case CONTENT:
                return onHideContent(layout);
            case LOADING:
                View loadingView = this.loadingView;
                return loadingView != null && onRemoveLoadingView(loadingView, layout);
            case ERROR:
                View errorView = this.errorView;
                return errorView != null && onRemoveErrorView(errorView, layout);
            case EMPTY:
                View emptyView = this.emptyView;
                return emptyView != null && onRemoveEmptyView(emptyView, layout);
        }
        return false;
    }

    private boolean enterState(int state) {
        VIEW layout = this.layout;
        if (layout == null) {
            return false;
        }
        switch (state) {
            case CONTENT:
                return onShowContent(layout);
            case LOADING:
                View loadingView = this.loadingView;
                return loadingView != null && onAddLoadingView(loadingView, layout);
            case ERROR:
                View errorView = this.errorView;
                return errorView != null && onAddErrorView(errorView, layout);
            case EMPTY:
                View emptyView = this.emptyView;
                return emptyView != null && onAddEmptyView(emptyView, layout);
        }
        return false;
    }


    @Override
    public final void loading() {
        moveToState(status, LOADING);
    }

    private void moveToState(int lastState, int newState) {
        if (lastState == newState) {
            return;
        }
        if (exitLastState(lastState)) {
            if (enterState(newState)) {
                for (OnStatusChangeListener listener : listeners) {
                    listener.onStatusChange(lastState, newState);
                }
                layout.requestApplyInsets();
                status = newState;
            } else {
                //恢复
                if (!enterState(lastState)) {
                    throw new IllegalArgumentException("状态不能前进，也不能恢复");
                }
            }
        }
        //exit失败的话都不管
    }

    @Override
    public final void showContent() {
        moveToState(status, CONTENT);
    }

    @Override
    public final void error() {
        moveToState(status, ERROR);
    }

    @Override
    public final void empty() {
        moveToState(status, EMPTY);
    }

    public void addOnStatusChangeListener(OnStatusChangeListener listener) {
        listeners.add(listener);
    }

    public void removeOnStatusChangeListener(OnStatusChangeListener listener) {
        listeners.remove(listener);
    }

    public void clearOnStatusChangeListener() {
        listeners.clear();
    }

    protected abstract boolean onAddLoadingView(@NonNull View loadingView, @NonNull VIEW layout);

    protected abstract boolean onRemoveLoadingView(@NonNull View loadingView, @NonNull VIEW layout);

    protected abstract boolean onAddEmptyView(@NonNull View loadingView, @NonNull VIEW layout);

    protected abstract boolean onRemoveEmptyView(@NonNull View loadingView, @NonNull VIEW layout);

    protected abstract boolean onAddErrorView(@NonNull View loadingView, @NonNull VIEW layout);

    protected abstract boolean onRemoveErrorView(@NonNull View loadingView, @NonNull VIEW layout);

    protected abstract boolean onHideContent(@NonNull VIEW layout);

    protected abstract boolean onShowContent(@NonNull VIEW layout);
}
